package com.blockmeta.bbs.businesslibrary.widget.chartview.Axis;

import com.blankj.utilcode.util.LogUtils;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.blockmeta.bbs.baselibrary.utils.FormatUtil;
import com.blockmeta.bbs.businesslibrary.widget.chartview.CandleData;
import com.blockmeta.bbs.businesslibrary.widget.chartview.ChartData;
import com.blockmeta.bbs.businesslibrary.widget.chartview.Layer.Layer;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class MoveCoordinate extends Coordinate
{
	protected static final Layer.ChartTypeEnum[] m_indicatorTypes = {Layer.ChartTypeEnum.MACD, Layer.ChartTypeEnum.OBV, Layer.ChartTypeEnum.KDJ, Layer.ChartTypeEnum.RSI,
			Layer.ChartTypeEnum.CCI, Layer.ChartTypeEnum.WR, Layer.ChartTypeEnum.ROC, Layer.ChartTypeEnum.STOCHTSI};
	@Override
	public void setData(ChartData pData)
	{
		List<Point> tXList = new ArrayList<Point>();
		List<Point> tYList = new ArrayList<Point>();

		if (pData != null)
		{
			ChartData.ChartPeroid mChartType = pData.getChartPeroid();
			Layer.ChartTypeEnum tLayerType = m_callback.getCharTypeEnum();
			m_ScaleFactor = m_callback.getScaleFactor();
			int tYTagCount = m_callback.getYTagCount();

			List<CandleData> tDataList = pData.getCandleData();

			m_nQueryCount = m_callback.getDisplayCount();//为一屏幕显示的个数

			int tStartIndex = pData.m_dataIndex;//为数据index的位置
			m_nStartIndex = pData.m_dataIndex;
			int nXTagCount = m_callback.getXTagCount();

			float tMaxValue = 0.f;
			float tMinValue = 0.f;
			Date tStrFlagDate = null;

			tSymBol = pData.getSymbol();

			boolean tSimpleMode = m_callback.isSimpleMode();
			int lastXIndex = 0;

			int minCount = Math.min(m_nStartIndex + m_callback.getDisplayCount(), pData.getCandleData().size());


			if(m_callback.isDrawAllData())//如果需要绘制全部数据的
			{
				tStartIndex = 0;
				m_nStartIndex = 0;
				minCount = pData.getCandleData().size();
				m_nQueryCount = pData.getCandleData().size();//为一屏幕显示的个数
			}


			try
			{
				for (int i = tStartIndex; i < minCount; i++)
				{
					CandleData tData = tDataList.get(i);


					Date tStrDate = null;

					tStrDate = TimeUtils.millis2Date(tData.getDate());

					float tHigh = -1;
					float tLow = -1;

					if (tSimpleMode)
					{
						tHigh = (float) tData.getDbClose();
						tLow = (float) tData.getDbClose();
					}
					else if (tLayerType == Layer.ChartTypeEnum.AREA)
					{
						tHigh = (float) tData.getDbClose();
						tLow = (float) tData.getDbClose();
					}
					else if (tLayerType == Layer.ChartTypeEnum.MoveBar)
					{
						tHigh = (float) tData.m_lVolume;
						tLow = (float) tData.m_lVolume;
					}
					else if(tLayerType == Layer.ChartTypeEnum.MACD || tLayerType == Layer.ChartTypeEnum.KDJ || tLayerType == Layer.ChartTypeEnum.RSI)
					{
						tHigh = (float) Math.max(Math.max(tData.getDbHigh(),tData.getDbOpen()),tData.getDbClose());
						tLow = (float) Math.min(Math.min(tData.getDbHigh(),tData.getDbOpen()),tData.getDbClose());
					}
					else if(tLayerType == Layer.ChartTypeEnum.OBV || tLayerType == Layer.ChartTypeEnum.CCI || tLayerType == Layer.ChartTypeEnum.WR)
					{
						tHigh = (float) tData.getDbOpen();
						tLow = (float) tData.getDbOpen();
					}
					else if(tLayerType == Layer.ChartTypeEnum.ROC || tLayerType == Layer.ChartTypeEnum.STOCHTSI)
					{
						tHigh = (float) Math.max(tData.getDbOpen(),tData.getDbClose());
						tLow = (float) Math.min(tData.getDbOpen(),tData.getDbClose());
					}
					else
					{
						tHigh = (float) tData.getDbHigh();
						tLow = (float) tData.getDbLow();
					}


					if (i == tStartIndex)
					{
						tMaxValue = tHigh;
						tMinValue = tLow;
						tStrFlagDate = getFirstDate(mChartType,tStrDate);
//						LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						m_KMaxValueIndex=i;
						m_KMinValueIndex=i;
					}
					else
					{
						if (tHigh >= tMaxValue)
						{
							tMaxValue = tHigh;
							m_KMaxValueIndex=i;
						}
						if (tLow <= tMinValue)
						{
							tMinValue = tLow;
							m_KMinValueIndex=i;
						}
					}


//					LogUtils.d("chart","i"+i+" tStrDate"+tStrDate);
					if (tStrDate.getTime() >= tStrFlagDate.getTime())
					{

						String tXText = null;
						Date tFlagDate = tStrFlagDate;
						Date tDate = tStrDate;

//						if(lastXIndex >= i - 2)//如果两个x坐标小于最小间距
//						{
////							tStrFlagDate = m_forDateFormat.format(getNextDate(mChartType, tDate,null));
////							FDTLogUtils.d("tingchart2","lastXIndex != 0 && lastXIndex == i - 1  tStrFlagDate"+tStrFlagDate+" tDate"+tDate+" lastXIndex"+lastXIndex);
//							continue;
//						}
//						lastXIndex = i;

						Calendar tCal = Calendar.getInstance();
						tCal.setTime(tStrDate);

						if (mChartType == ChartData.ChartPeroid.CP_1min)
						{
							if(tStrDate.getTime() == tStrFlagDate.getTime()) {
								tXText = m_DateTimeFormat.format(tDate);
								tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
//								LogUtils.d("chart","add tXList:"+tXText);
								tCal.add(Calendar.MINUTE,1);
							}
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else if (mChartType == ChartData.ChartPeroid.CP_5min)
						{
							if(tStrDate.getTime() == tStrFlagDate.getTime()) {
								tXText = m_DateTimeFormat.format(tDate);
								tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
//								LogUtils.d("chart","add tXList:"+tXText);
								tCal.add(Calendar.MINUTE,1);
							}
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else if (mChartType == ChartData.ChartPeroid.CP_15min)
						{
							if(tStrDate.getTime() == tStrFlagDate.getTime()) {
								tXText = m_DateTimeFormat.format(tDate);
								tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
//								LogUtils.d("chart","add tXList:"+tXText);
								tCal.add(Calendar.MINUTE,1);
							}
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else if (mChartType == ChartData.ChartPeroid.CP_30min)
						{
							if(tStrDate.getTime() == tStrFlagDate.getTime()) {
								tXText = m_DateTimeFormat.format(tDate);
								tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
//								LogUtils.d("chart","add tXList:"+tXText);
								tCal.add(Calendar.MINUTE,1);
							}
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else if (mChartType == ChartData.ChartPeroid.CP_1hour)
						{
							tXText = m_Format.format(tDate);
							tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else if (mChartType == ChartData.ChartPeroid.CP_4hour)
						{
							tXText = m_Format.format(tDate);
							tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else if (mChartType == ChartData.ChartPeroid.CP_1day)
						{
							tXText = m_Format.format(tDate);
							tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else if (mChartType == ChartData.ChartPeroid.CP_1week)
						{
							tXText = m_5YearFormat.format(tDate);
							tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else if (mChartType == ChartData.ChartPeroid.CP_1month)
						{
							tXText = m_5YearFormat.format(tDate);
							tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}
						else
						{
							tXText = m_Format.format(tDate);
							tXList.add(new Point(0, 0, 0, 0, true, tXText, (i + 1 - tStartIndex)));
							tStrFlagDate = getNextDate(mChartType, tCal.getTime());
//							LogUtils.d("chart","tStrFlagDate:"+tStrFlagDate);
						}




//						FDTLogUtils.d("tingchart2","next x tStrFlagDate"+tStrFlagDate);
					}
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
				LogUtils.d("chart","coordinate error"+e.getMessage());
			}

			//判断需不需要加入昨结
			if (tMaxValue == 0.f && tMinValue == 0.f)
			{

			}
			else
			{
				if (m_callback != null && m_callback.isShowYesterClose()
						&& (tLayerType != Layer.ChartTypeEnum.MoveBar && tLayerType != Layer.ChartTypeEnum.MACD && tLayerType != Layer.ChartTypeEnum.RSI && tLayerType != Layer.ChartTypeEnum.KDJ))//不需要画昨结线就不把昨天的价格放入计算
				{
					float tYesterClose = m_callback.getYesterClose();
					if (tYesterClose > tMaxValue)
					{
						tMaxValue = tYesterClose;
					}
					else if (tYesterClose < tMinValue)
					{
						tMinValue = tYesterClose;
					}
				}
			}



			m_bDigit = 2;//价格小数位数
			if (tSymBol != null)
			{
				m_bDigit = tSymBol.getDigit();
			}

			float tRate = (float) Math.pow(10, m_bDigit);

			float tTempStandard = 5.f / tRate;

			if(tLayerType != Layer.ChartTypeEnum.MoveBar && tLayerType != Layer.ChartTypeEnum.RSI && tLayerType != Layer.ChartTypeEnum.KDJ)//最大最小都为0或相等时时候计算最小间距
			{
				if (tMaxValue == 0 && tMinValue == 0)
				{
					float tDiff = 2.f / (float) Math.pow(10, 2);
					tMaxValue = tDiff;
					tMinValue = 0;
				}

				if (tMaxValue == tMinValue)
				{
					float tDiff = 2.f / (float) Math.pow(10, 2);
					tMaxValue = tMinValue + tDiff;
				}
			}
			else
			{
				if (tMaxValue == 0 && tMinValue == 0)
				{
					float tDiff = 2.f;
					tMaxValue = tDiff;
					tMinValue = 0;
				}

				if (tMaxValue == tMinValue)
				{
					float tDiff = 2.f;
					tMinValue = tMaxValue / 2;
				}
			}




			if(tLayerType == Layer.ChartTypeEnum.KMaMoveBar || tLayerType == Layer.ChartTypeEnum.MoveBar) //k线需要和均线最大最小值进行比较取大范围值
			{


				List<CandleData> additionData = null;
				float tAdditionMaxValue = Float.MIN_VALUE;
				float tAdditionMinValue = Float.MAX_VALUE;
				additionData = m_callback.getAdditionMinMax();
				if(additionData != null && additionData.size() >= minCount)
				{
					for (int i = tStartIndex; i < minCount; i++)
					{
						CandleData tData = additionData.get(i);
						float tHigh = -1;
						float tLow = -1;
//						float tAdditionOpen = (float)tData.getDbOpen();
//						float tAdditionClose = (float)tData.getDbClose();
//						float tAdditionHigh = (float)tData.getDbHigh();
						tHigh = (float) tData.getHighForward();// Math.max(tAdditionOpen,Math.max(tAdditionClose,tAdditionHigh));
//						tAdditionOpen = tAdditionOpen == 0.f ? Float.MAX_VALUE : tAdditionOpen;
//						tAdditionClose = tAdditionClose == 0.f ? Float.MAX_VALUE : tAdditionClose;
//						tAdditionHigh = tAdditionHigh == 0.f ? Float.MAX_VALUE : tAdditionHigh;
						tLow = (float) tData.getLowForward();// Math.min(tAdditionOpen,Math.min(tAdditionClose,tAdditionHigh));

						if (i == tStartIndex)
						{
							tAdditionMaxValue = tHigh;
							tAdditionMinValue = tLow;
						}
						else
						{
							if (tHigh > tAdditionMaxValue)
							{
								tAdditionMaxValue = tHigh;
							}
							if (tLow < tAdditionMinValue)
							{
								tAdditionMinValue = tLow;
							}
						}
					}
					tMaxValue = Math.max(tMaxValue,tAdditionMaxValue);
					tMinValue = Math.min(tMinValue,tAdditionMinValue);
					if(tLayerType != Layer.ChartTypeEnum.MoveBar) {
						BigDecimal b = new BigDecimal(tMaxValue);
						tMaxValue = b.setScale(m_bDigit, RoundingMode.UP).floatValue();
						BigDecimal b2 = new BigDecimal(tMinValue);
						tMinValue = b2.setScale(m_bDigit, RoundingMode.DOWN).floatValue();
					}

//					FDTLogUtils.d("tingchartout","tMaxValue"+tMaxValue+"tMinValue"+tMinValue);
				}
			}

			if(m_callback.isNeedUpDownSpace())//如果需要放大间距的
			{
				float valueToAdd = (tMaxValue - tMinValue)/10;
				tMaxValue += valueToAdd;
				tMinValue -= valueToAdd;
//				tMinValue = tMinValue <= 0 ? 0 : tMinValue;
			}


			if (tLayerType == Layer.ChartTypeEnum.MoveBar)
			{

				m_nYIntervalCount = 2;
				m_nYIntervalStandard = (tMaxValue - tMinValue) / 2;

				if (tMaxValue > 0)
				{
					long maxValue = (long) tMaxValue;
					long midValue = maxValue >> 1;


//					String mid = CommonLib.longToVolumeHumanReadableFormat(midValue, 0);

					String symbolUnit = "";

//					if(tSymBol != null && tSymBol.getMarket().getAppMarket() == AppEnv.AppMarket.SC
//							&& tSymBol.getSubMarket() != AppEnv.SubMarket.US && tSymBol.getSubMarket() != AppEnv.SubMarket.HK)//如果是a股，变成手
//					{
//						symbolUnit = "手";
//					}

					String max = FormatUtil.longToVolumeHumanReadableFormat(maxValue, 2);
					if(tYTagCount != 0)
					{
						tYList.add(new Point(0, 0, 0, 0, true, "", 1));
					}
					else
					{
						tYList.add(new Point(0, 0, 0, 0, true, symbolUnit, 1));
					}
					tYList.add(new Point(0, 0, 0, 0, true, "", 2));
					tYList.add(new Point(0, 0, 0, 0, true, max, 3));
				}
			}
			else if(tLayerType == Layer.ChartTypeEnum.MACD || tLayerType == Layer.ChartTypeEnum.RSI || tLayerType == Layer.ChartTypeEnum.KDJ)
			{
				m_nYIntervalCount = 2;
				float tY0 = 0.f;
				if(tLayerType == Layer.ChartTypeEnum.KDJ || tLayerType == Layer.ChartTypeEnum.RSI)
				{
					tY0 = 50;
					m_bDigit = 0;
				}
				boolean updist = Math.abs(tMaxValue - tY0) > Math.abs(tMinValue - tY0) ? true : false;
				if(updist)
				{
					tMinValue = tY0 - Math.abs(tMaxValue - tY0);
				}
				else
				{
					tMaxValue = tY0 + Math.abs(tMinValue - tY0);
				}


				m_nYIntervalStandard = (tMaxValue - tMinValue) / 2;

//				FDTLogUtils.d("tingchart","macd tMaxValue"+tMaxValue+" tMinValue"+tMinValue);
//				if (tMaxValue > 0)
//				{
//					long maxValue = tMaxValue;
//					long midValue = ()



				String max = FormatUtil.getFormatString(tMaxValue, m_bDigit);
				String min = FormatUtil.getFormatString(tMinValue, m_bDigit);
				String mid = FormatUtil.getFormatString(tY0, m_bDigit);

				tYList.add(new Point(0, 0, 0, 0, true, min, 1));
				tYList.add(new Point(0, 0, 0, 0, true, mid, 2));
				tYList.add(new Point(0, 0, 0, 0, true, max, 3));
//				}
			}
			else if(Arrays.asList(m_indicatorTypes).contains(tLayerType))
			{
				m_nYIntervalCount = 2;
				if(tYTagCount != 0)
				{
					m_nYIntervalCount = tYTagCount;
				}
				int tStandard = 1;
				int nMaxValue = (int) Math.ceil(tMaxValue * tRate);
				int nMinValue = (int) Math.floor(tMinValue * tRate);

				nMaxValue = ((int) (nMaxValue / tStandard) + (nMaxValue % tStandard == 0 ? 0 : 1)) * tStandard;
				nMinValue = ((int) (nMinValue / tStandard)) * tStandard;

				int tValueDist = nMaxValue - nMinValue;

				while (((tValueDist / tStandard) % m_nYIntervalCount) != 0)
				{
					nMaxValue += tStandard;
					tValueDist += tStandard;
				}

				tMaxValue = nMaxValue / tRate;
				tMinValue = nMinValue / tRate;
				tTempStandard = (tValueDist / m_nYIntervalCount) / tRate;
				m_nYIntervalStandard = tTempStandard;

//				FDTLogUtils.d("tingchartout","m_nYIntervalStandard"+m_nYIntervalStandard+"tRate"+tRate);

				for (int i = 0; i <= m_nYIntervalCount; i++)
				{
					String tCurrentValue = FormatUtil.getFormatString(tMinValue + tTempStandard * i, m_bDigit);
//					FDTLogUtils.d("tingchartout","tCurrentValue"+tCurrentValue);
					tYList.add(new Point(0, 0, 0, 0, true, tCurrentValue, (i + 1)));
				}
			}
			else
			{

				m_nYIntervalCount = 4;
				if(tYTagCount != 0)
				{
					m_nYIntervalCount = tYTagCount;
				}
				int tStandard = 1;
				int nMaxValue = (int) Math.ceil(tMaxValue * tRate);
				int nMinValue = (int) Math.floor(tMinValue * tRate);

				nMaxValue = ((int) (nMaxValue / tStandard) + (nMaxValue % tStandard == 0 ? 0 : 1)) * tStandard;
				nMinValue = ((int) (nMinValue / tStandard)) * tStandard;

				int tValueDist = nMaxValue - nMinValue;

				while (((tValueDist / tStandard) % m_nYIntervalCount) != 0)
				{
					nMaxValue += tStandard;
					tValueDist += tStandard;
				}

				tMaxValue = nMaxValue / tRate;
				tMinValue = nMinValue / tRate;
				tTempStandard = (tValueDist / m_nYIntervalCount) / tRate;
				m_nYIntervalStandard = tTempStandard;

//				FDTLogUtils.d("tingchartout","m_nYIntervalStandard"+m_nYIntervalStandard+"tRate"+tRate);

				for (int i = 0; i <= m_nYIntervalCount; i++)
				{
					String tCurrentValue = FormatUtil.getFormatString(tMinValue + tTempStandard * i, m_bDigit);
//					FDTLogUtils.d("tingchartout","tCurrentValue"+tCurrentValue);
					tYList.add(new Point(0, 0, 0, 0, true, tCurrentValue, (i + 1)));
				}


//				int tStandard = 5;
//				int nMaxValue = (int) (tMaxValue * tRate);
//				int nMinValue = (int) (tMinValue * tRate);
//
//				nMaxValue = (nMaxValue / tStandard + (nMaxValue % tStandard == 0 ? 0 : 1)) * tStandard;
//				nMinValue = (nMinValue / tStandard) * tStandard;
//
//				int tValueDist = nMaxValue - nMinValue;
//
//				int tTemp = 5;
//
//				while (tValueDist / tTemp > 10)
//				{
//					tTemp *= 2;
//				}
//
//				m_nYIntervalCount = tValueDist / tTemp;
//
//				tMaxValue = nMaxValue / tRate;
//				tMinValue = nMinValue / tRate;
//				tTempStandard = tTemp / tRate;
//				m_nYIntervalStandard = tTempStandard;
//
//				for (int i = 0; i <= m_nYIntervalCount; i++)
//				{
//					String tCurrentValue = CommonLib.getFormatString(tMaxValue - tTempStandard * (m_nYIntervalCount - i), m_bDigit);
//					tYList.add(new Point(0, 0, 0, 0, true, tCurrentValue, (i + 1)));
//				}
			}

			m_fMaxValue = tMaxValue;
			m_fMinValue = tMinValue;
		}
		m_xAxis.setPointList(tXList);
		m_yAxis.setPointList(tYList);
	}

}
